// phalanx constant.hpp.cu header file

// Copyright (c) 2010 - 2011 Kohei Takahashi (Flast).
// Distributed under the MIT license. for more detail see COPYING.

#ifndef IG_PHALANX_MATH_CONSTANT_HPP_CU_ONCE_
#define IG_PHALANX_MATH_CONSTANT_HPP_CU_ONCE_

#include <phalanx/config.hpp.cu>

#include <cmath>
#include <cfloat>

namespace phalanx
{

namespace math
{

#define CONSTANT_IMPL( name, value ) \
  struct name \
  { \
      template < typename T > \
      PHALANX_CONFIG_DEFAULT_FUNCTION( true ) \
      operator T( void ) const \
      { return static_cast< T >( value ); } \
  }

CONSTANT_IMPL( zero_, 0 );

CONSTANT_IMPL( one_, 1 );

CONSTANT_IMPL( e_,
#if defined( M_El )
    M_El
#elif defined( M_E )
    M_E
#else
    2.7182818284590452353602874713526625L
#endif
  );

CONSTANT_IMPL( pi_,
#if defined( M_PIl )
    M_PIl
#elif defined( M_PI )
    M_PI
#else
    3.1415926535897932384626433832795029L
#endif
  );

struct epsilon_
{
private:
    template < typename T >
    PHALANX_CONFIG_DEFAULT_FUNCTION( true )
    T
    impl( void ) const
    { return DBL_EPSILON; }

public:
    template < typename T >
    PHALANX_CONFIG_DEFAULT_FUNCTION( true )
    operator T( void ) const
    { return impl< T >(); }
};

template <>
PHALANX_CONFIG_DEFAULT_FUNCTION( true )
float
epsilon_::impl< float >( void ) const
{ return FLT_EPSILON; }

#undef CONSTANT_IMPL

} // namespace math

} // namespace phalanx

#endif // IG_PHALANX_MATH_CONSTANT_HPP_CU_ONCE_

